package com.kerry.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.DatagramChannel;

import java.net.InetSocketAddress;

import org.apache.log4j.Logger;

public class ServerUDPChannelFactory {
	private static final Logger LOGGER = Logger.getLogger(ServerUDPChannelFactory.class);

	protected static Channel createAcceptorChannel(
			final ChannelType channelType,
			final InetSocketAddress localAddress,
			final ServerUDPHandler serverHandler) {
		final Bootstrap serverBootstrap = ServerUDPBootstrapFactory
				.createServerBootstrap(channelType);
		serverBootstrap.option(ChannelOption.SO_REUSEADDR, false).handler(
				new ChannelInitializer<DatagramChannel>() {
			@Override
			protected void initChannel(final DatagramChannel ch)
					throws Exception {
				final ChannelPipeline pipeline = ch.pipeline();
				// pipeline.addLast("readTimeoutHandler", new
				// ReadTimeoutHandler(60));//这是读写超时操作，实际上在UDP上没有多少的意义
				pipeline.addLast("handler", serverHandler);
			}
		});
		LOGGER.info("open udp socket on port:"+localAddress.getPort());
		try {

			ChannelFuture channelFuture = serverBootstrap.bind(
					new InetSocketAddress(localAddress.getPort())).sync();

			// channelFuture.channel().closeFuture().awaitUninterruptibly();//.awaitUninterruptibly();
			channelFuture.awaitUninterruptibly();
			if (channelFuture.isSuccess()) {
				return channelFuture.channel();
			} else {
				LOGGER.warn(String.format(
						"Failed to open upd socket! Cannot bind to port: %d!",
						localAddress.getPort()));
			}
		} catch (InterruptedException e) {
			LOGGER.error("Failed to create acceptor upd socket.", e);
		}
		return null;

	}

}
